package com.itheima.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*
* 模拟一个消费者
* */
public class Client {
    public static void main(String[] args) {

        //被代理的对象 必须是final
        final Producer producer = new Producer();
   //.     producer.saleProduct(1000f);

        /*
        * 动态代理
        * 不修改源码的情况下 对方法进行增强
        * 分类:
        * 基于子类的动态代理     第三方cglib库  需要导入依赖
        * 基于接口的动态代理    jdk官方      不需要依赖
        * 如何创建代理对象:
        * 使用Proxy类的newProxyInstance方法
        * 创建代理类的要求:
        * 被代理类至少实现一个接口
        *
        * newProxyInstance方法的参数
        *    classloader  用于加载代理对象字节码的,和被代理对象使用相同的类加载器
        *    class[]     用于代理对象和被代理对象有相同的方法
        *    InvocationHandler  用于提供增强代码
        * */


        //基于接口的动态代理
      IProducer proxyProducer= (IProducer)Proxy.newProxyInstance(producer.getClass().getClassLoader(), producer.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     *
                     * @param proxy   代理对象的引用
                     * @param method   当前执行的方法
                     * @param args      当前执行方法所需要的参数
                     * @return        和被代理对象有相同的返回值
                     * @throws Throwable
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object returnValue=null;

                        //获取被代理对象的参数
                        Float money = (Float) args[0];
                        if("saleProduct".equals(method.getName())){
                            //提供增强的代码
                            returnValue= method.invoke(producer,money*0.8f);
                        }
                        return returnValue;
                    }
                });


      //动态代理
        proxyProducer.saleProduct(1000f);
    }
}
